package java_thinking.unit_21._21_2;

import net.jcip.annotations.ThreadSafe;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Desc:   4-7 基于委托的车辆追踪器 使用不可变的Point类和线程安全的ConcurrentMap
 *              委托给单个线程安全的状态变量
 * @author: cww
 * @DateTime: 2019-06-02 22:42
 */
@ThreadSafe
public class DelegatingVehicleTracker {
    private final ConcurrentHashMap<String, Point> locations;
    private final Map<String, Point> unmodifiableMap;

    public DelegatingVehicleTracker(Map<String, Point> points) {
        this.locations = new ConcurrentHashMap<String, Point>();
        //返回指定地图的不可修改视图
        this.unmodifiableMap = Collections.unmodifiableMap(locations);
    }

    /**
     * 如果线程A调用 getLocations ，而线程B在随后修改了某些点的位置，那么返回给线程A的Map中将反映出这个变化
     * @return
     */
    public Map<String, Point> getLocations() {
        return unmodifiableMap;
    }

    /**
     * 4-8  返回 locations 的浅拷贝而非实时拷贝，看具体业务需求
     * @return
     */
    public Map<String, Point> getLocationsAsStatic() {
        return Collections.unmodifiableMap(
                new HashMap<String, Point>(locations));
    }

    /**
     * 直接返回Map中的对象，因为已经是不可变的 Point 类，发布出去也是安全的
     * @param id
     * @return
     */
    public Point getLocation(String id) {
        return locations.get(id);
    }

    /**
     * 更新Point也并没有使用任何显示的同步，所有对状态的访问都由 ConcurrentHashMap 来管理 委托
     * @param id
     * @param x
     * @param y
     * @throws IllegalAccessException
     */
    public void setLocation(String id, int x, int y) throws IllegalAccessException {
        if (locations.replace(id, new Point(x,y)) == null) {
            throw new IllegalAccessException("No such id : "+ id);
        }
    }
}
